import datetime

class TimeRange(object):
    def __init__(self, start=None, end=None):
        self._start = None
        self._end = None
        self.start = start
        self.end = end

    def __eq__(self, other):
        if isinstance(other, TimeRange):
            return self.start == other.start and self.end == other.end
        return False

    def __hash__(self):
        return hash((self.start, self.end))

    @property
    def start(self):
        return self._start

    @start.setter
    def start(self, value):
        if isinstance(value, str):
            if ':' in value and len(value) > 16:
                value = datetime.datetime.strptime(value, '%Y-%m-%d %H:%M:%S')
            elif ':' in value and len(value) == 16:
                value = datetime.datetime.strptime(value, '%Y-%m-%d %H:%M')
            else:
                value = datetime.datetime.strptime(value, '%Y-%m-%d')
        self._start = value

    @property
    def end(self):
        return self._end

    @end.setter
    def end(self, value):
        if isinstance(value, str):
            if ':' in value and len(value) > 16:
                value = datetime.datetime.strptime(value, '%Y-%m-%d %H:%M:%S')
            elif ':' in value and len(value) == 16:
                value = datetime.datetime.strptime(value, '%Y-%m-%d %H:%M')
            else:
                value = datetime.datetime.strptime(value, '%Y-%m-%d')
        self._end = value

    @property
    def duration(self):
        return self.end - self.start if self.start and self.end else datetime.timedelta()

    @property
    def date_list(self):
        _start = self.start
        _ret = [_start]
        while _start < self.end:
            _start += datetime.timedelta(days=1)
            _ret.append(_start)
        return _ret

    def include(self, value):
        value = ConvertUtil.convert_to_datetime(value)
        if not isinstance(value, datetime.datetime):
            return False
        return self.start <= value <= self.end

    @classmethod
    def date_list_new(cls, start, end, measure=None):
        _start = start
        _ret = [_start]
        while _start < end:
            _start += datetime.timedelta(days=1)
            if _start > end:
                break
            _ret.append(_start)
        count = len(_ret)
        if measure:
            last_day_len = round(float((end - _ret[count - 1]).seconds) / float(measure), 1)
        else:
            last_day_len = round(float((end - _ret[count - 1]).seconds) / float(3600 * 8), 1)
        return _ret, last_day_len

    @classmethod
    def get_ranges_date_list(cls, ranges):
        _ret = []
        for _r in ranges:
            _ret += _r.date_list
        return _ret

class ConvertUtil(object):
    @classmethod
    def convert_measure_value(cls, value, measure):
        """
        从分钟往度量值上转
        :param value:
        :param measure:
        :return:
        """
        if not value:
            return value
        if measure == 'h':
            return round(value / 60, 2)
        elif measure == 'd':
            return round(value / 480, 2)
        else:
            return value

    @classmethod
    def convert_to_minute_by_measure(cls, value, measure):
        """
        从度量值往分钟上转
        :param value:
        :param measure:
        :return:
        """
        if measure == 'd':
            return value * 60 * 8
        elif measure == 'h':
            return value * 60
        else:
            return value

    @classmethod
    def convert_to_datetime(cls, value):
        if isinstance(value, str):
            if ':' in value and len(value) > 16:
                value = datetime.datetime.strptime(value, '%Y-%m-%d %H:%M:%S')
            elif ':' in value and len(value) == 16:
                value = datetime.datetime.strptime(value, '%Y-%m-%d %H:%M')
            else:
                value = datetime.datetime.strptime(value, '%Y-%m-%d')
        return value